package com.example.dingdong.websocketHandler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.*;

import com.alibaba.fastjson.JSONObject;
import com.example.dingdong.websocketService.WebSocketService;
import com.example.dingdong.websocketUtil.WebSocketConst;



/**
 * 创建处理器
 */
public class MyHandler implements WebSocketHandler  {
	
	private static final Logger log = LoggerFactory.getLogger(MyHandler.class);

	@Autowired
	private WebSocketService webSocketService;
    /**
     * 在WebSocket协商成功后调用，并且打开WebSocket连接准备使用
     * @param webSocketSession webSocketSession
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
    	try {
//			String token = webSocketSession.getUri().toString().split("\\?")[1];
            String remoteIP = webSocketSession.getRemoteAddress().getHostString();

			// 添加 Session
			webSocketService.getSessions().put(remoteIP, webSocketSession);
			webSocketService.getIpAddressRelateKeepAliveTime().put(remoteIP, WebSocketConst.KEEP_ALIVE_TIME);

			log.info("****** ipAddress:" + remoteIP + " 在线人数:" + webSocketService.getSessions().size() + " ******");
		} catch (Exception e) {
			log.error("WS连接请求格式错误，正确格式: ws://ip:port/wsresult?token  当前传入: " + webSocketSession.getUri().toString(), e);
		}
    }
    /**
     * 在网络套接字连接关闭后或在传输错误发生后调用。
     * 尽管从技术上讲，会话可能仍然是开放的，但取决于底层实现，在这一点上发送消息是不鼓励的，而且很可能不会成功。
     * @param webSocketSession webSocketSession
     * @param closeStatus closeStatus
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
    	try {
    		//String token = webSocketSession.getUri().toString().split("\\?")[1];
            String remoteIP = webSocketSession.getRemoteAddress().getHostString();

			// 删除 Session
			webSocketService.getSessions().remove(remoteIP);
			webSocketService.getIpAddressRelateKeepAliveTime().remove(remoteIP);

			log.warn("****** WS Close ipAddress:" + remoteIP + " 在线人数:" + webSocketService.getSessions().size() + " ******");
		} catch (Exception e) {
			log.error("WebSocket 关闭连接，close 连接失败! 来源: " + webSocketSession.getUri().toString() + "    错误原因:", e);
		}
    }


    /**
     * 当一个新的WebSocket消息到达时调用
     * @param webSocketSession webSocketSession
     * @param webSocketMessage webSocketMessage
     * @throws Exception 异常
     */
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
    	String msg = (String) webSocketMessage.getPayload();
		try {
			JSONObject data = JSONObject.parseObject(msg);
			String type = data.getString(WebSocketConst.TYPE);

			// 心跳发送
			if (WebSocketConst.HEART.equals(type)) {
				webSocketService.addJsonObjHeartToSend(webSocketSession);
			}

			// 恢复存活时间
//			String token = webSocketSession.getUri().toString().split("\\?")[1];
            String remoteIP = webSocketSession.getRemoteAddress().getHostString();
			webSocketService.getIpAddressRelateKeepAliveTime().put(remoteIP, WebSocketConst.KEEP_ALIVE_TIME);
		} catch (Exception e) {
			log.error("WebSocket 消息接收出错! 来源: " + webSocketSession.getUri().toString() + "    错误原因: ", e);
		}
    }

    /**
     * 处理来自底层WebSocket消息传输的错误
     * @param webSocketSession webSocketSession
     * @param throwable 错误
     * @throws Exception 异常
     */
    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
    	try {
    		//			String token = webSocketSession.getUri().toString().split("\\?")[1];
            String remoteIP = webSocketSession.getRemoteAddress().getHostString();

			// 删除 Session
			webSocketService.getSessions().remove(remoteIP);
			webSocketService.getIpAddressRelateKeepAliveTime().remove(remoteIP);

			// 关闭连接
			if (webSocketSession.isOpen()) {
				webSocketSession.close();
			}

			log.error("****** WS Error  token:" + remoteIP + " 在线人数:" + webSocketService.getSessions().size() + " ******",throwable);
		} catch (Exception e) {
			log.error("WebSocket 出错关闭连接，close 连接失败!  来源: " + webSocketSession.getUri().toString() + "    错误原因: ", e);
		}
    }

    
    /**
     * WebSocketHandler是否处理部分消息
     * @return 标志
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}
